package com.momoauth.api_client.controller;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.momoauth.api_client.entity.Department;
import com.momoauth.api_client.entity.Role;
import com.momoauth.api_client.entity.User;
import com.momoauth.api_client.entity.User_Role;
import com.momoauth.api_client.mapper.DepartmentMapper;
import com.momoauth.api_client.mapper.RoleMapper;
import com.momoauth.api_client.mapper.UserMapper;
import com.momoauth.api_client.mapper.UserRoleMapper;
import com.momoauth.api_client.utils.SecurityUtils;
import com.momoauth.common.core.result.ResponseResurt;
import com.momoauth.common.log.annotation.SystemLog;
import com.momoauth.common.security.annotation.RequiresRoles;
import com.momoauth.common.security.enumeration.Logical;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

@RestController
@RequestMapping("/user")
@Api(tags = "用户")
@RequiresRoles(value = {"超级管理员","普通管理员"}, logical = Logical.OR)
public class UserController {

    @Resource
    UserMapper userMapper;

    @Resource
    UserRoleMapper userRoleMapper;

    @Resource
    RoleMapper roleMapper;

    @Resource
    DepartmentMapper departmentMapper;

    @Resource
    SecurityUtils securityUtils;

    /**
     * 用户列表
     * @param user
     * @return
     */
    @ApiOperation(value = "用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "currentPage", value = "当前页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "页数", required = true),
            @ApiImplicitParam(name = "status", value = "状态", required = false, defaultValue = "0"),
            @ApiImplicitParam(name = "keywords", value = "关键词", required = false)
    })
    @RequestMapping(value = "/getUserList", method = RequestMethod.GET)
    @SystemLog(value = "用户列表", description = "ApiClient测试数据", insertSql = true)
    public ResponseResurt getUserList(User user) {
        Page<User> page = new Page<>(user.getCurrentPage(),user.getPageSize());
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(!StringUtils.isEmpty(user.getKeywords()),"realName", user.getKeywords());
        queryWrapper.eq(user.getStatus() != 0,"status", user.getStatus());
        queryWrapper.eq("isDelete", 0);
        queryWrapper.orderByDesc("userId"); //按主键倒序排序
        page.setRecords(userMapper.getUserList(page, queryWrapper));
        return ResponseResurt.success().data(page);
    }

    /**
     * 可用的角色列表
     * @return
     */
    @ApiOperation(value = "可用的角色列表")
    @RequestMapping(value = "/getAvailableRoleList", method = RequestMethod.GET)
    public ResponseResurt getAvailableRoleList() {
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1);
        queryWrapper.eq("isDelete", 0);
        List<Role> roleList = roleMapper.selectList(queryWrapper);
        return ResponseResurt.success().data(roleList);
    }

    /**
     * 可用的顶级部门列表
     * @return
     */
    @ApiOperation(value = "可用的顶级部门列表")
    @RequestMapping(value = "/getAvailableTopDepartmentList", method = RequestMethod.GET)
    public ResponseResurt getAvailableTopDepartmentList() {
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1);
        queryWrapper.eq("isDelete", 0);
        queryWrapper.eq("parentId", 0);
        queryWrapper.select("deptId","deptName");
        List<Department> departmentList = departmentMapper.selectList(queryWrapper);
        return ResponseResurt.success().data(departmentList);
    }

    /**
     * 可用的子部门列表
     * @param department
     * @return
     */
    @ApiOperation(value = "可用的子部门列表")
    @ApiImplicitParam(name = "parentId", value = "父部门ID", required = true)
    @RequestMapping(value = "/getChildrenDepartmentListByDeptId", method = RequestMethod.GET)
    public ResponseResurt getChildrenDepartmentListByDeptId(Department department) {
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1);
        queryWrapper.eq("isDelete", 0);
        queryWrapper.eq("parentId", department.getParentId());
        queryWrapper.select("deptId","deptName");
        List<Department> departmentList = departmentMapper.selectList(queryWrapper);
        return ResponseResurt.success().data(departmentList);
    }

    /**
     * 创建用户
     * @param user
     * @param bindingResult
     * @param roleList
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "创建用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true),
            @ApiImplicitParam(name = "password", value = "密码", required = true),
            @ApiImplicitParam(name = "realName", value = "真实姓名", required = true),
            @ApiImplicitParam(name = "roleList", value = "用户角色（列表）", required = true),
            @ApiImplicitParam(name = "dept_id", value = "部门ID（外键）", required = true),
            @ApiImplicitParam(name = "status", value = "状态", required = true)
    })
    @RequestMapping(value = "/createUser", method = RequestMethod.POST)
    @Transactional(rollbackFor={Exception.class})
    public ResponseResurt createUser(
            @Validated User user,
            BindingResult bindingResult,
            @RequestParam String roleList
    ) throws Exception {
        //非法参数验证
        if(bindingResult.hasErrors()){
            String errorMsg = bindingResult.getFieldError().getDefaultMessage();
            return ResponseResurt.error().msg(errorMsg);
        }
        //查询是否已存在同名用户
        Integer isExist = userMapper.existUserOfSameName(user.getUsername());
        if (isExist != null) {
            return ResponseResurt.error().msg("很抱歉，已存在同名用户。");
        }
        //创建用户并绑定用户角色
        if (createUser(user) > 0) {
            createUserRole(roleList, user.getUserId(), 1);
            return ResponseResurt.success().msg("恭喜您，注册成功。");
        }
        return ResponseResurt.error().msg("很抱歉，注册失败！");
    }

    //创建用户信息
    private int createUser(User user) {
        //这里随机生成四位数作为盐值
        String salt = RandomStringUtils.randomNumeric(4);
        user.setSalt(salt);
        //把原始密码加上盐值进行MD5加密
        String password = securityUtils.getMD5Pwd(user.getPassword(), salt);
        user.setPassword(password);
        return userMapper.insert(user);
    }

    //创建用户角色
    private void createUserRole(String roleList, Long user_id, int type){
        if(roleList != null && !roleList.isEmpty()){
            long count = 0; //计数
            List<User_Role> jsonArray = JSON.parseArray(roleList, User_Role.class);
            if (type == 1) { // 新增
                for (User_Role user_role : jsonArray) {
                    user_role.setUser_id(user_id);
                    // 判断是否已存在相同的角色
                    count = userRoleMapper.countUserRole(user_role.getUser_id(), user_role.getRole_id());
                    if (count <= 0) {
                        userRoleMapper.insert(user_role);
                    }
                }
            } else { // 修改
                // 清除该用户所有角色重新添加
                userRoleMapper.deleteAllUserRole(user_id);
                for (User_Role user_role : jsonArray) {
                    user_role.setUser_id(user_id);
                    userRoleMapper.insert(user_role);
                }
            }
        }
    }

    /**
     * 修改用户
     * @param user
     * @param roleList
     * @param request
     * @return
     */
    @ApiOperation(value = "修改用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID（主键）", required = true),
            @ApiImplicitParam(name = "realName", value = "真实名称", required = true),
            @ApiImplicitParam(name = "roleList", value = "用户角色（列表）", required = true),
            @ApiImplicitParam(name = "dept_id", value = "部门ID", required = true),
            @ApiImplicitParam(name = "status", value = "状态", required = true)
    })
    @RequestMapping(value = "/updateUser", method = RequestMethod.POST)
    @Transactional(rollbackFor={Exception.class})
    public ResponseResurt updateUser(User user, @RequestParam String roleList, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Long userId = Long.parseLong(securityUtils.getClaimName(token, "userId"));
        // 不可修改自身信息
        if (userId.equals(user.getUserId())) {
            return ResponseResurt.error().msg("请不要修改自身信息！");
        }
        // 查询当前版本号
        long version = userMapper.selectById(user.getUserId()).getVersion();
        user.setVersion(version);
        // 执行更新操作
        int isUpdate = userMapper.updateById(user);
        if (isUpdate > 0) {
            if (roleList.length() > 0) {
                createUserRole(roleList, user.getUserId(), 2);
            }
            return ResponseResurt.success().msg("恭喜您，修改成功。");
        }
        return ResponseResurt.error().msg("很抱歉，修改失败！");
    }

    /**
     * 删除用户
     * @param user
     * @param request
     * @return
     */
    @ApiOperation(value = "删除用户")
    @ApiImplicitParam(name = "userId", value = "用户ID（主键）", required = true)
    @RequestMapping(value = "/deleteUser", method = RequestMethod.GET)
    public ResponseResurt deleteUser(User user, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Long userId = Long.parseLong(securityUtils.getClaimName(token, "userId"));
        // 不可删除自身
        if (userId.equals(user.getUserId())) {
            return ResponseResurt.error().msg("很抱歉，不可删除自身！");
        }
        //执行更新操作（逻辑删除）
        int isDelete = userMapper.deleteUserById(user);
        if (isDelete > 0) {
            return ResponseResurt.success().msg("恭喜您，删除成功。");
        }
        return ResponseResurt.error().msg("很抱歉，删除失败！");
    }

    /**
     * 用户详情
     * @param user
     * @return
     */
    @ApiOperation(value = "用户详情")
    @ApiImplicitParam(name = "userId", value = "用户ID（主键）", required = true)
    @RequestMapping(value = "/getUserById", method = RequestMethod.GET)
    public ResponseResurt getUserById(User user) {
        Map<String, Object> map = new HashMap<>();
        user = userMapper.getUserById(user.getUserId());
        map.put("user", user);
        List<User_Role> user_roleList = userRoleMapper.getUserRoleList(user.getUserId());
        map.put("user_roleList", user_roleList);
        return ResponseResurt.success().data(map);
    }
}
